export function randomString(len) {
    len = len || 32
    let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
    let maxPos = $chars.length
    let pwd = ''
    for (let i = 0; i < len; i++) {
        pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
    }
    return pwd
}


// 定义一个深拷贝函数  接收目标target参数
export function deepClone(target) {
    // 定义一个变量
    let result
    // 如果当前需要深拷贝的是一个对象的话
    if (typeof target === 'object') {
        // 如果是一个数组的话
        if (Array.isArray(target)) {
            result = [] // 将result赋值为一个数组，并且执行遍历
            for (let i in target) {
                // 递归克隆数组中的每一项
                result.push(deepClone(target[i]))
            }
            // 判断如果当前的值是null的话；直接赋值为null
        } else if (target === null) {
            result = null
            // 判断如果当前的值是一个RegExp对象的话，直接赋值
        } else if (target.constructor === RegExp) {
            result = target
        } else {
            // 否则是普通对象，直接for in循环，递归赋值对象的所有值
            result = {}
            for (let i in target) {
                result[i] = deepClone(target[i])
            }
        }
        // 如果不是对象的话，就是基本数据类型，那么直接赋值
    } else {
        result = target
    }
    // 返回最终结果
    return result
}

export function defaultValue(value, defaultValue) {
    if (isUndefined(value) || isNull(value)) {
        return defaultValue
    }
    return value
}

export function isNull(value) {
    return toString.call(value, String) === '[object Null]'
}

export function isEmpty(value) {
    if (isUndefined(value) || isNull(value)) {
        return true
    }
    if ((isString(value) || isArray(value)) && value.length === 0) {

        return true
    }
    if (isObject(value) && Object.values(value).length === 0 && !(value instanceof Date)) {
        return true
    }
    if (isObject(value) && value instanceof Date && !value) {
        return true
    }
    return false
}

export function isObject(value) {
    return toString.call(value, String) === '[object Object]'
}

export function isArray(value) {
    return toString.call(value, String) === '[object Array]'
}

export function isString(value) {
    return typeof value === 'string'
}

export function isUndefined(value) {
    return typeof value === 'undefined'
}

export function isTrue(value) {
    if (isBoolean(value)) {
        return value
    } else if (isNumeric(value)) {
        return value != 0
    } else if (isString(value)) {
        return value === 'true'
    }
    return false
}

export function isBoolean(value) {
    return typeof value === 'boolean'
}

export function isFunction(value) {
    return typeof value === 'function'
}

export function isNumber(value) {
    return !isNaN(value) && typeof value === 'number'
}

export function isNumeric(value) {
    return isNumber(Number(value))
}

export function isInteger(value, isStrict = true) {
    if (isStrict) {
        return Number.isInteger(value)
    }
    return Number.isInteger(Number(value))
}

/**
 * 加法
 * @param arg1
 * @param arg2
 * @returns {number}
 */
export function bcAdd(arg1, arg2) {
    let r1, r2, m
    try {
        r1 = arg1.toString().split('.')[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split('.')[1].length
    } catch (e) {
        r2 = 0
    }
    m = Math.pow(10, Math.max(r1, r2))
    return (arg1 * m + arg2 * m) / m
}

/**
 * 乘法
 * @param arg1
 * @param arg2
 * @returns {number}
 */
export function bcMul(arg1, arg2) {
    let m = 0, s1 = arg1.toString(), s2 = arg2.toString()
    try {
        m += s1.split('.')[1].length
    } catch (e) {
    }
    try {
        m += s2.split('.')[1].length
    } catch (e) {
    }
    return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
}

/**
 * 除法
 * @param arg1
 * @param arg2
 * @returns {number}
 */
export function bcDiv(arg1, arg2) {
    let t1 = 0, t2 = 0, r1, r2
    try {
        t1 = arg1.toString().split('.')[1].length
    } catch (e) {
    }
    try {
        t2 = arg2.toString().split('.')[1].length
    } catch (e) {
    }
    r1 = Number(arg1.toString().replace('.', ''))
    r2 = Number(arg2.toString().replace('.', ''))
    return (r1 / r2) * Math.pow(10, t2 - t1)
}

export function bcSub(arg1, arg2) {
    let r1, r2, max, min
    try {
        r1 = arg1.toString().split('.')[1].length
    } catch (e) {
        r1 = 0
    }
    try {
        r2 = arg2.toString().split('.')[1].length
    } catch (e) {
        r2 = 0
    }
    max = Math.pow(10, Math.max(r1, r2))
    //动态控制精度长度
    min = (r1 >= r2) ? r1 : r2
    return ((arg1 * max - arg2 * max) / max).toFixed(min)
}

export const bcComp = (a, b) => {
    a = Number(a)
    b = Number(b)
    if (isNaN(a)) {
        a = 0
    }
    if (isNaN(b)) {
        b = 0
    }
    if (a === b) {
        return 0
    }
    return a > b ? 1 : -1
}

export function formatMoney(val, v2 = 2) {
    val = Number(val)
    if (isNaN(val)) {
        return 0
    }
    return Number(val.toFixed(v2))
}



